package com.hskn.hss.task;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hskn.hss.module.alarmcar.entity.AlarmCar;
import com.hskn.hss.module.alarmcar.mapper.AlarmCarMapper;
import com.hskn.hss.module.carPlan.entity.CarPlan;
import com.hskn.hss.module.carPlan.mapper.CarPlanMapper;
import com.hskn.hss.module.carPlan.service.CarPlanService;
import com.hskn.hss.module.carPlanCollectPoint.entity.CarPlanCollectPoint;
import com.hskn.hss.module.carPlanCollectPoint.mapper.CarPlanCollectPointMapper;
import com.hskn.hss.module.carTrack.entity.CarTrack;
import com.hskn.hss.module.carTrack.mapper.CarTrackMapper;
import com.hskn.hss.module.carTrack.service.CarTrackService;
import com.hskn.hss.module.depart.entity.SysDepart;
import com.hskn.hss.module.depart.service.ISysDepartService;
import com.hskn.hss.module.employeeTrack.entity.EmployeeTrack;
import com.hskn.hss.module.employeeTrack.mapper.EmployeeTrackMapper;
import com.hskn.hss.module.gridSnapshot.entity.GridSnapshot;
import com.hskn.hss.module.gridSnapshot.mapper.GridSnapshotMapper;
import com.hskn.hss.module.jobset.entity.Jobset;
import com.hskn.hss.module.jobset.mapper.JobsetMapper;
import com.hskn.hss.module.oilDevice.domain.StateOilDevice;
import com.hskn.hss.module.oilDevice.service.IStateOilDeviceService;
import com.hskn.hss.module.rptCarWork.entity.RptCarWork;
import com.hskn.hss.module.rptCarWork.mapper.RptCarWorkMapper;
import com.hskn.hss.module.rptEmployeeWork.entity.RptEmployeeWork;
import com.hskn.hss.module.rptEmployeeWork.mapper.RptEmployeeWorkMapper;
import com.hskn.hss.module.tlcar.entity.TlCar;
import com.hskn.hss.module.tlcar.service.ITlCarService;
import com.hskn.hss.module.tlcartype.entity.TlCarType;
import com.hskn.hss.module.tlcartype.service.ITlCarTypeService;
import com.hskn.hss.task.OutOilBo.OutOilBo;
import com.hskn.hss.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Slf4j
@Configuration
@EnableScheduling
@Component
public class WorkTask {

    @Autowired
    JobsetMapper jobsetMapper;
    @Autowired
    LocationUtils locationUtil;
    @Autowired
    private RptCarWorkMapper rptCarWorkMapper;
    @Autowired
    private CarTrackMapper carTrackMapper;
    @Autowired
    private CarTrackService carTrackService;
    @Value("${switch.timed_task}")
    private Boolean timed_task;
    @Autowired
    private ITlCarService carService;
    @Autowired
    private AlarmCarMapper alarmCarMapper;
    @Autowired
    private ITlCarTypeService carTypeService;
    @Autowired
    private ISysDepartService departService;
    @Autowired
    private IStateOilDeviceService stateOilDeviceService;
    @Autowired
    private RptEmployeeWorkMapper rptEmployeeWorkMapper;
    @Autowired
    private EmployeeTrackMapper employeeTrackMapper;
    @Autowired
    private GridSnapshotMapper gridSnapshotMapper;
    @Autowired
    private CarPlanMapper carPlanMapper;
    @Autowired
    private CarPlanCollectPointMapper carPlanCollectPointMapper;
    @Autowired
    private CarPlanService carPlanService;

//    /**
//     * 机械作业-里程完成度
//     */
//    @Scheduled(cron = "0 4/10 * * * ?")
//    public void mileageComplete() {
//        if (timed_task) {
//
//            long carStartTime = System.currentTimeMillis();
//            log.info("===================机械作业、垃圾清运、垃圾转运-里程完成度，任务开始===============");
//            Date now = new Date();
//            String nowStr = StringUtils.dateToStr(now, "yyyy-MM-dd");
//            //遍历 车辆考勤，根据条件获取当天有作业的车辆，查询车辆的工作里程，更新车辆考勤表
//            QueryWrapper<RptCarWork> carWorkQueryWrapper = new QueryWrapper<>();
//            carWorkQueryWrapper.lambda().eq(RptCarWork::getWorkDate, nowStr);
//            carWorkQueryWrapper.lambda().eq(RptCarWork::getWorkType, 2);
//            List<RptCarWork> rptCarWorkList = rptCarWorkMapper.selectList(carWorkQueryWrapper);
//            for (RptCarWork rptCarWork : rptCarWorkList) {
//                String gridId = rptCarWork.getGridId();
//                //作业类型：2机械清扫；3垃圾清运；4垃圾转运
//                Integer workType = rptCarWork.getWorkType();
//                Integer allProgress = rptCarWork.getAllProgress();
//                if (null == allProgress || allProgress <= 0) {
//                    log.error("网格没有配置里程，gridId:{}", gridId);
//                    continue;
//                }
//                Integer nowProgress = rptCarWork.getNowProgress();
//                // 获取阀值
//                Integer jobSetId = workType + 1;
//                Jobset jobset = jobsetMapper.selectById(jobSetId);
//                Double kmOkThreshold;
//                kmOkThreshold = jobset.getKmOkThreshold();
//                if (now.compareTo(rptCarWork.getPlanStartTime()) >= 0 && now.compareTo(rptCarWork.getPlanEndTime()) <= 0 && rptCarWork.getStatus() == 0) {
//                    rptCarWork.setStatus(1);//进行中：当日排班进行中；
//                }
//                if (rptCarWork.getStatus() == 1 || rptCarWork.getStatus() == 0) {
//                    if (nowProgress > 0) {
//                        /** 更新 完成状态 和 当前进度 **/
//                        if (nowProgress > allProgress) {
//                            nowProgress = allProgress;
//                        }
//                        Integer completePercent = nowProgress * 100 / allProgress;
//                        // 完成状态
//                        if (now.compareTo(rptCarWork.getPlanEndTime()) <= 0) {
//                            if (completePercent >= kmOkThreshold) {
//                                rptCarWork.setStatus(3);//考勤时间结束，已完成作业。
//                            }
//                        } else {
//                            if (completePercent < kmOkThreshold) {
//                                rptCarWork.setStatus(2);//未完成：考勤时间结束，未完成作业；
//                            } else {
//                                rptCarWork.setStatus(3);//考勤时间结束，已完成作业。
//                            }
//                        }
//                        // 当前里程
//                        rptCarWork.setNowProgress(nowProgress);
//                        // 完成百分比
//                        rptCarWork.setCompletePercent(completePercent);
//                    } else {
//                        rptCarWork.setStatus(0);
//                    }
//                    rptCarWorkMapper.updateById(rptCarWork);
//                }
//            }
//            long carEndTime = System.currentTimeMillis();
//            log.info("===================机械作业、垃圾清运、垃圾转运-里程完成度，任务结束===============执行时间(毫秒)：{}", carEndTime - carStartTime);
//        }
//    }


    /**
     * 垃圾清运里程完成度
     */
    @Scheduled(cron = "0 5/10 * * * ?")
    public void trashPickup() {
        if (timed_task) {

            long carStartTime = System.currentTimeMillis();
            log.info("===================垃圾清运里程完成度，任务开始===============");
            String workDate = StringUtils.dateToStr(new Date(), "yyyy-MM-dd");
            carPlanService.updateTrashPickup(workDate);
            long carEndTime = System.currentTimeMillis();
            log.info("===================垃圾清运里程完成度，任务结束===============执行时间(毫秒)：{}", carEndTime - carStartTime);
        }
    }

    /**
     * 人员作业完成度
     */
    @Scheduled(cron = "0 6/10 * * * ?")
    public void employeeWorkPlan() {
        if (timed_task) {
            long carStartTime = System.currentTimeMillis();
            log.info("===================人员里程里程完成度，任务开始===============");
            Date now = new Date();
            String workDate = StringUtils.dateToStr(now, "yyyy-MM-dd");
            QueryWrapper<GridSnapshot> gridSnapshotQueryWrapper = new QueryWrapper<>();
            gridSnapshotQueryWrapper.lambda().eq(GridSnapshot::getDate, workDate);
            List<GridSnapshot> gridSnapshotList = gridSnapshotMapper.selectList(gridSnapshotQueryWrapper);
            Map<String, GridSnapshot> gridSnapshotMap = gridSnapshotList.stream().collect(Collectors.groupingBy(GridSnapshot::getGridId, Collectors.collectingAndThen(Collectors.toList(), grids -> grids.get(0))));

            QueryWrapper<RptEmployeeWork> rptEmployeeWorkQueryWrapper = new QueryWrapper<>();
            rptEmployeeWorkQueryWrapper.lambda().eq(RptEmployeeWork::getWorkDate, workDate);
            List<RptEmployeeWork> rptEmployeeWorkList = rptEmployeeWorkMapper.selectList(rptEmployeeWorkQueryWrapper);
//            Map<String, List<RptEmployeeWork>> rptEmployeeWorkMap = rptEmployeeWorkList.stream().collect(Collectors.groupingBy(RptEmployeeWork::getEmployeeId));

            QueryWrapper<EmployeeTrack> employeeTrackQueryWrapper = new QueryWrapper<>();
            employeeTrackQueryWrapper.lambda().orderByAsc(EmployeeTrack::getTimestamp);
            employeeTrackQueryWrapper.lambda().eq(EmployeeTrack::getWorkDay, workDate);
            List<EmployeeTrack> employeeTrackList = employeeTrackMapper.selectList(employeeTrackQueryWrapper);
            Map<String, List<EmployeeTrack>> employeeTrackMap = employeeTrackList.stream().collect(Collectors.groupingBy(EmployeeTrack::getEmployeeId));


            for (RptEmployeeWork rptEmployeeWork : rptEmployeeWorkList) {

                List<EmployeeTrack> employeeTrackList3 = new ArrayList<>();

                List<EmployeeTrack> employeeTrackList2 = employeeTrackMap.get(rptEmployeeWork.getEmployeeId());
                if (null != employeeTrackList2) {
                    for (EmployeeTrack employeeTrack : employeeTrackList2) {
                        GridSnapshot gridSnapshot = gridSnapshotMap.get(rptEmployeeWork.getGridId());
                        if (null != gridSnapshot) {
                            boolean isInGrid = DistanceUtils.insideCopyGrid(Double.parseDouble(employeeTrack.getLng()), Double.parseDouble(employeeTrack.getLat()), gridSnapshot);
                            if (isInGrid) {
                                employeeTrackList3.add(employeeTrack);
                            }
                        }
                    }
                }

                Long secondsTotal = 0L;
                for (int i = 1; i < employeeTrackList3.size(); i++) {
                    if (now.compareTo(rptEmployeeWork.getPlanStartTime()) >= 0 && now.compareTo(rptEmployeeWork.getPlanEndTime()) <= 0 && rptEmployeeWork.getStatus() == 0) {
                        rptEmployeeWork.setStatus(1);//进行中：当日排班进行中；
                    }
                    if (rptEmployeeWork.getStatus() == 1 || rptEmployeeWork.getStatus() == 0) {
                        Long timestamp = employeeTrackList3.get(i).getTimestamp().getTime() - employeeTrackList3.get(i - 1).getTimestamp().getTime();
                        Long seconds = timestamp / 1000;
                        if (seconds < 1800) {
                            secondsTotal += seconds;
                        }
                        Long planSeconds = (rptEmployeeWork.getPlanEndTime().getTime() - rptEmployeeWork.getPlanStartTime().getTime()) / 1000;

                        Jobset jobset = jobsetMapper.selectById(2);
                        Double motionOkThreshold = jobset.getMotionOkThreshold();
                        if (secondsTotal > 0) {
                            Long completePercent = secondsTotal * 100 / planSeconds;
                            if (now.compareTo(rptEmployeeWork.getPlanEndTime()) <= 0) {
                                if (completePercent >= motionOkThreshold) {
                                    rptEmployeeWork.setStatus(3);//考勤时间结束，已完成作业。
                                }
                            } else {
                                if (completePercent < motionOkThreshold) {
                                    rptEmployeeWork.setStatus(2);//未完成：考勤时间结束，未完成作业；
                                } else {
                                    rptEmployeeWork.setStatus(3);//考勤时间结束，已完成作业。
                                }
                            }
                            rptEmployeeWork.setNowProgress(Integer.parseInt(secondsTotal.toString()));
                            rptEmployeeWork.setCompletePercent(Integer.parseInt(completePercent.toString()));
                        } else {
                            rptEmployeeWork.setStatus(0);
                        }

                        rptEmployeeWorkMapper.updateById(rptEmployeeWork);
                    }

                }

            }
            long carEndTime = System.currentTimeMillis();
            log.info("===================人员里程里程完成度，任务结束===============执行时间(毫秒)：{}", carEndTime - carStartTime);
        }
    }

    /**
     * 每日凌晨00:59:59秒执行一次，统计每辆车的油量、行驶等信息
     */
    @Scheduled(cron = "59 59 0 * * ?")
    private void stateOilDeviceScheduled() {
        Date date = new Date(Tools.getDateAddDay(new Date(), -1));
        List<CarTrack> carTrackListBeginSevenDay = carTrackService.getCarTracks(null, date);
        addOil(carTrackListBeginSevenDay, date);
    }

    public void addOil(List<CarTrack> carTrackListBeginSevenDay, Date yesterday) {
        Map<String, List<CarTrack>> carTrackListBeginSevenDayMap = GroupingByUtils.getGroupingForMapList(carTrackListBeginSevenDay,
                CarTrack::getCarId);
        Map<String, TlCar> carMap = carService.getCarMap(new QueryWrapper<>());
        QueryWrapper<AlarmCar> alarmCarQueryWrapper = new QueryWrapper<>();
        Date startTime = Tools.getDateForBegin(yesterday);
        Date endTime = Tools.getDateForEnd(yesterday);
        alarmCarQueryWrapper.lambda().between(AlarmCar::getCreateTime, startTime, endTime);
        alarmCarQueryWrapper.lambda().eq(AlarmCar::getAlarmTypeName, "漏油");
        alarmCarQueryWrapper.lambda().select(AlarmCar::getCarId, AlarmCar::getAlarmStartTime, AlarmCar::getAlarmEndTime,
                AlarmCar::getAlarmValue
        );
        List<AlarmCar> alarmCarList = alarmCarMapper.selectList(alarmCarQueryWrapper);
        alarmCarList = alarmCarList.stream().filter(x -> Objects.nonNull(x.getAlarmStartTime()) && Objects.nonNull(x.getAlarmEndTime())).collect(Collectors.toList());
        Map<String, List<AlarmCar>> alarmListMap = GroupingByUtils.getGroupingForMapList(alarmCarList, AlarmCar::getCarId);
        Map<String, OutOilBo> carYesterdayAlarmMap = new HashMap<>();
        for (String carId : alarmListMap.keySet()) {
            List<AlarmCar> alarmCars = alarmListMap.get(carId);
            if (!Objects.nonNull(alarmCars)) {
                continue;
            }
            if (!carMap.containsKey(carId)) {
                continue;
            }
            //昨天车辆漏油报警过程中，使用油量（包括正常和漏油的油量）
            BigDecimal alarmOilWear = BigDecimal.ZERO;
            //昨天车辆漏油报警过程中，总行驶里程
            BigDecimal alarmTotalMileage = BigDecimal.ZERO;
            //昨天车辆漏油报警次数
            Integer outOilCount = alarmCars.size();
            for (AlarmCar alarmCar : alarmCars) {
                if (!carTrackListBeginSevenDayMap.containsKey(carId) || carTrackListBeginSevenDayMap.get(carId).isEmpty()) {
                    break;
                }
                Predicate<CarTrack> inTimes = carTrack -> (carTrack.getTimestamp().getTime() >= alarmCar.getAlarmStartTime().getTime())
                        && (carTrack.getTimestamp().getTime() <= alarmCar.getAlarmEndTime().getTime());
                List<CarTrack> alarmCarTrackList = carTrackListBeginSevenDayMap.get(carId).stream().filter(inTimes).collect(Collectors.toList());
                for (CarTrack carTrack : alarmCarTrackList) {
                    Double distance = Double.parseDouble(String.valueOf(carTrack.getDistanceBetween()));
                    alarmTotalMileage = (MathUtils.getBigDecimal(distance).add(alarmTotalMileage));
                }
                alarmOilWear = alarmOilWear.add(alarmCar.getAlarmValue());
            }
            carYesterdayAlarmMap.put(carId, new OutOilBo(alarmOilWear, alarmTotalMileage, outOilCount));
        }
        List<StateOilDevice> stateOilDeviceList = initStateOilDevice(carMap, carTrackListBeginSevenDay, yesterday, carYesterdayAlarmMap);
        stateOilDeviceService.saveBatch(stateOilDeviceList);
    }

    private List<StateOilDevice> initStateOilDevice(Map<String, TlCar> carMap, List<CarTrack> carTrackListBeginSevenDay, Date yesterday, Map<String, OutOilBo> carYesterdayAlarmMap) {
        Predicate<CarTrack> isYesterday = carTrack -> Tools.isSameDay(carTrack.getTimestamp(), yesterday);
        Predicate<CarTrack> isNotYesterday = carTrack -> !Tools.isSameDay(carTrack.getTimestamp(), yesterday);
        List<CarTrack> carTrackYesterdayList = carTrackListBeginSevenDay.stream().filter(isYesterday).filter(x -> x.getOilMass().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());
        List<CarTrack> carTrackYesterdayList2 = carTrackListBeginSevenDay.stream().filter(isYesterday).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(carTrackYesterdayList)) {
            return new ArrayList<>();
        }

        Map<String, List<CarTrack>> carTrackYesterdayMap = GroupingByUtils.getGroupingForMapList(carTrackYesterdayList, CarTrack::getCarId);
        Map<String, List<CarTrack>> carTrackYesterdayMap2 = GroupingByUtils.getGroupingForMapList(carTrackYesterdayList2, CarTrack::getCarId);
        Map<String, TlCarType> carTypeMap = carTypeService.getCarTypeMap(new QueryWrapper<>());
        Map<String, SysDepart> departMap = departService.getDepartMap(new QueryWrapper<>());
        StateOilDevice stateOilDevice = new StateOilDevice();
        List<StateOilDevice> stateOilDeviceList = new ArrayList<>();

        for (String carId : carTrackYesterdayMap2.keySet()) {
            //异常耗油
            BigDecimal alarmOilWear = BigDecimal.ZERO;
            //异常里程
            BigDecimal alarmTotalMileage = BigDecimal.ZERO;
            if (carYesterdayAlarmMap.containsKey(carId)) {
                alarmOilWear = carYesterdayAlarmMap.get(carId).getAlarmOilWear();
                alarmTotalMileage = carYesterdayAlarmMap.get(carId).getAlarmTotalMileage();
            }

            // 最大速度
            BigDecimal maxSpeed = BigDecimal.ZERO;
            // 开始时间
            Date startDate = null;
            // 结束时间
            Date endDate = null;
            // 开始位置
            String startPosition = "";
            // 结束位置
            String endPosition = "";

            List<CarTrack> oneCarTrackYesterday = carTrackYesterdayMap.get(carId);
            List<CarTrack> oneCarTrackYesterday2 = carTrackYesterdayMap2.get(carId);
            List<CarTrack> carTrackList2ForMaxSpeed = new ArrayList<>();
            if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(oneCarTrackYesterday2)) {
                carTrackList2ForMaxSpeed = oneCarTrackYesterday2.stream().sorted(Comparator.comparing(CarTrack::getSpeed)).collect(Collectors.toList());
            }
            if (Objects.nonNull(carTrackList2ForMaxSpeed) && carTrackList2ForMaxSpeed.size() > 0) {
                maxSpeed = new BigDecimal(carTrackList2ForMaxSpeed.get(carTrackList2ForMaxSpeed.size() - 1).getSpeed());
            }
            List<CarTrack> carTrackList2ForTimestamp = new ArrayList<>();
            if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(oneCarTrackYesterday2)) {
                carTrackList2ForTimestamp = oneCarTrackYesterday2.stream().sorted(Comparator.comparing(CarTrack::getTimestamp)).collect(Collectors.toList());
            }
            // 行驶次数
            Integer runCount = 0;
            //行驶时长
            BigDecimal moveSecondSum = BigDecimal.ZERO;

            int maxNotMoveNumLimit = 10;
            int notMoveNum = 0;
            for (int i = 1; i < carTrackList2ForTimestamp.size(); i++) {
                CarTrack preCarTrack = carTrackList2ForTimestamp.get(i - 1);
                CarTrack currentCarTrack = carTrackList2ForTimestamp.get(i);
                if (Objects.isNull(currentCarTrack.getTimestamp()) || Objects.isNull(preCarTrack.getTimestamp())) {
                    continue;
                }
                if (locationUtil.checkTwoPointSameComplete(Double.parseDouble(currentCarTrack.getLng())
                        , Double.parseDouble(currentCarTrack.getLat()), Double.parseDouble(preCarTrack.getLng())
                        , Double.parseDouble(preCarTrack.getLat()))) {

                    notMoveNum++;
                } else {
                    Long timeDifference = currentCarTrack.getTimestamp().getTime() - preCarTrack.getTimestamp().getTime();
                    double differenceMeter = locationUtil.getDistance(currentCarTrack.getLat(), currentCarTrack.getLng(), preCarTrack.getLat(), preCarTrack.getLng());
                    //两个定位数据，距离小于20米，时间大于10分钟，认为没有移动【解决车辆停止一段时间后，再启动电源，然后立马关闭电源的情况】
                    if (realMove(differenceMeter, timeDifference)) {
                        moveSecondSum = moveSecondSum.add(new BigDecimal(timeDifference));
                        //if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(xxx)) {
                        if (Objects.isNull(startDate)) {
                            startDate = currentCarTrack.getTimestamp();
                        }
                        endDate = currentCarTrack.getTimestamp();
                        //lng,lat
                        if (StringUtils.isEmpty(startPosition)) {
                            startPosition = currentCarTrack.getLng() + "," + currentCarTrack.getLat();
                        }
                        endPosition = currentCarTrack.getLng() + "," + currentCarTrack.getLat();
                        // }
                        if (notMoveNum >= maxNotMoveNumLimit) {
                            runCount++;
                        }
                        notMoveNum = 0;
                    } else {
                        notMoveNum++;
                    }
                }
            }

            //加油量
            BigDecimal addOilWear = BigDecimal.ZERO;
            //开始油量
            BigDecimal startOilMss = BigDecimal.ZERO;
            //总里程数
            BigDecimal totalMileage = BigDecimal.ZERO;
            //漏油量
            BigDecimal outOilNum = BigDecimal.ZERO;
            //结束油量
            BigDecimal endOilMss = BigDecimal.ZERO;
            //油耗
            BigDecimal oilWear = BigDecimal.ZERO;
            //平均油耗
            BigDecimal averageOil = BigDecimal.ZERO;
            Integer addOilCount = 0;

            if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(oneCarTrackYesterday)) {
                for (int i = 1; i < oneCarTrackYesterday.size(); i++) {
                    Double addNumber = null == oneCarTrackYesterday.get(i).getAddOilNum() ? 0D : oneCarTrackYesterday.get(i).getAddOilNum();
                    addOilWear = addOilWear.add(MathUtils.getBigDecimal(addNumber));
                }
            }
            if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(oneCarTrackYesterday2)) {
                for (int i = 1; i < oneCarTrackYesterday2.size(); i++) {
                    Double distance = Double.parseDouble(String.valueOf(oneCarTrackYesterday2.get(i).getDistanceBetween()));
                    totalMileage = (MathUtils.getBigDecimal(distance).add(totalMileage));
                }
            }

            addOilWear = addOilWear.setScale(4, BigDecimal.ROUND_HALF_UP);
            if (addOilWear.compareTo(BigDecimal.ZERO) > 0) {
                addOilCount++;
            }
            if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(oneCarTrackYesterday)) {
                startOilMss = oneCarTrackYesterday.get(0).getOilMass();
                endOilMss = oneCarTrackYesterday.get(oneCarTrackYesterday.size() - 1).getOilMass();
            }
            //油耗
            oilWear = MathUtils.getBigDecimal(startOilMss).subtract(MathUtils.getBigDecimal(endOilMss)).add(addOilWear).setScale(4, BigDecimal.ROUND_HALF_UP);
            //平均油耗计算方法
            List<CarTrack> carTrackListBeginSevenDay2 = carTrackListBeginSevenDay.stream().filter(isNotYesterday).collect(Collectors.toList());
            averageOil = carTrackService.getAlarmOilWearNum(carId, carTrackListBeginSevenDay2, alarmTotalMileage);
            if (carMap.containsKey(carId)) {
                outOilNum = BigDecimal.ZERO;
                if (alarmOilWear != null && alarmOilWear.compareTo(BigDecimal.ZERO) > 0) {
                    outOilNum = alarmOilWear.subtract(averageOil);
                }
                if (outOilNum != null && outOilNum.compareTo(BigDecimal.ZERO) < 0) {
                    outOilNum = BigDecimal.ZERO;
                }
                stateOilDevice = new StateOilDevice(
                        carMap.get(carId).getCarnumber(), addOilWear, outOilNum.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : outOilNum, oilWear.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : oilWear, carYesterdayAlarmMap.containsKey(carId) ? carYesterdayAlarmMap.get(carId).getOutCount() : 0,
                        addOilCount, carMap.get(carId).getCardeptid(), carId, carMap.get(carId).getCartypeid(),
                        carTypeMap.get(carMap.get(carId).getCartypeid()).getTypename(), totalMileage.divide(new BigDecimal(1000), 2, BigDecimal.ROUND_HALF_UP),
                        carMap.get(carId).getCarcategory(), departMap.get(carMap.get(carId).getCardeptid()).getOrgType(),
                        departMap.get(carMap.get(carId).getCardeptid()).getDepartName(), new Date(), new Date(), yesterday, maxSpeed, moveSecondSum, startDate, endDate,
                        StringUtils.isNotEmpty(startPosition) ? locationUtil.getAddress(startPosition.split(",")[0], startPosition.split(",")[1]) : ""
                        , StringUtils.isNotEmpty(endPosition) ? locationUtil.getAddress(endPosition.split(",")[0], endPosition.split(",")[1]) : "", runCount
                );

                stateOilDevice.setId(StringUtils.uuid());
                stateOilDeviceList.add(stateOilDevice);

            }

        }
        return stateOilDeviceList;

    }


    public boolean realMove(double differenceMeter, Long timeDifference) {
        //两个定位数据，距离小于20米，且时间间隔大于10分钟，认为没有移动【解决车辆停止一段时间后，再启动电源，然后立马关闭电源的情况】
        return timeDifference <= 10 * 60 * 1000 || !(differenceMeter < 20);
    }
}
